<template>
  <el-dialog
    ref="dialogRef"
    v-model="visible"
    :append-to-body="appendToBody"
    :fullscreen="fullscreen"
    :custom-class="customClass"
    :lock-scroll="lockScroll"
    :close-on-click-modal="closeOnClickModal"
    :modal="modal"
    :close-on-press-escape="closeOnPressEscape"
    :title="title"
    :show-close="showClose"
    :top="top"
    :destroy-on-close="destroyOnClose"
    :width="width"
    :center="center"
    :before-close="onVisibleChange"
    @close="handleClose"
    @closed="handleClosed"
    @open="handleOpen"
    @opened="handleOpened"
  >
    <!-- 自定义头部 -->
    <template v-if="$slots.header" #header>
      <slot name="header"></slot>
    </template>
    <template v-else-if="showHeader" #header>
      <div class="qs-dialog-header" :class="{ 'qs-dialog-header-draggable': draggable }" @mousedown="startDrag">
        <div class="qs-dialog-title">
          <slot name="title">{{ title }}</slot>
        </div>
        <div class="qs-dialog-header-actions">
          <slot name="header-actions"></slot>
        </div>
      </div>
    </template>

    <!-- 内容区域 -->
    <div class="qs-dialog-body" :class="{ 'is-loading': loading }">
      <el-loading v-if="loading" background="rgba(255, 255, 255, 0.7)" :lock="true" :text="loadingText" />
      <slot></slot>
    </div>

    <!-- 自定义底部 -->
    <template v-if="$slots.footer" #footer>
      <slot name="footer"></slot>
    </template>
    <template v-else-if="showFooter" #footer>
      <div class="qs-dialog-footer">
        <el-button v-if="showCancelButton" @click="handleCancel">{{ cancelText }}</el-button>
        <el-button v-if="showConfirmButton" :loading="confirmLoading" type="primary" @click="handleConfirm">
          {{ confirmText }}
        </el-button>
        <slot name="footer-actions"></slot>
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { defineEmits, defineProps, watch } from 'vue'
import { useDialog } from '../../hooks/useDialog'

// 组件属性定义
const props = defineProps({
  // 显示控制
  modelValue: {
    type: Boolean,
    default: false,
  },

  // 基础属性
  title: {
    type: String,
    default: '',
  },
  width: {
    type: [String, Number],
    default: '50%',
  },
  fullscreen: {
    type: Boolean,
    default: false,
  },
  top: {
    type: String,
    default: '15vh',
  },

  // 行为控制
  modal: {
    type: Boolean,
    default: true,
  },
  appendToBody: {
    type: Boolean,
    default: false,
  },
  lockScroll: {
    type: Boolean,
    default: true,
  },
  customClass: {
    type: String,
    default: '',
  },
  closeOnClickModal: {
    type: Boolean,
    default: true,
  },
  closeOnPressEscape: {
    type: Boolean,
    default: true,
  },
  showClose: {
    type: Boolean,
    default: true,
  },
  beforeClose: {
    type: Function,
    default: undefined,
  },
  destroyOnClose: {
    type: Boolean,
    default: false,
  },
  center: {
    type: Boolean,
    default: false,
  },

  // 拖拽
  draggable: {
    type: Boolean,
    default: false,
  },

  // 头部控制
  showHeader: {
    type: Boolean,
    default: true,
  },

  // 底部控制
  showFooter: {
    type: Boolean,
    default: true,
  },
  showCancelButton: {
    type: Boolean,
    default: true,
  },
  showConfirmButton: {
    type: Boolean,
    default: true,
  },
  cancelText: {
    type: String,
    default: '取消',
  },
  confirmText: {
    type: String,
    default: '确定',
  },
  confirmLoading: {
    type: Boolean,
    default: false,
  },

  // 加载状态
  loading: {
    type: Boolean,
    default: false,
  },
  loadingText: {
    type: String,
    default: '加载中...',
  },
})

// 组件事件
const emit = defineEmits(['update:modelValue', 'open', 'opened', 'close', 'closed', 'cancel', 'confirm'])

// 使用对话框Hook
const { visible, dialogRef, position, open, close, setTitle, setLoading, confirm, startDrag, centerDialog, onVisibleChange } = useDialog({
  visible: props.modelValue,
  title: props.title,
  beforeClose: props.beforeClose,
  draggable: props.draggable,
})

// 同步modelValue和visible
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal !== visible.value) {
      visible.value = newVal
    }
  }
)

watch(
  () => visible.value,
  (newVal) => {
    if (newVal !== props.modelValue) {
      emit('update:modelValue', newVal)
    }
  }
)

// 监听标题变化
watch(
  () => props.title,
  (newTitle) => {
    setTitle(newTitle)
  }
)

// 监听加载状态变化
watch(
  () => props.loading,
  (newLoading) => {
    setLoading(newLoading)
  }
)

// 事件处理
const handleOpen = () => {
  emit('open')
}

const handleOpened = () => {
  emit('opened')
}

const handleClose = () => {
  emit('close')
}

const handleClosed = () => {
  emit('closed')
}

const handleCancel = () => {
  emit('cancel')
  close()
}

const handleConfirm = async () => {
  try {
    const result = await confirm()
    emit('confirm', result)
    close()
  } catch (error) {
    console.error('确认失败:', error)
  }
}

// 组件方法暴露
defineExpose({
  // 暴露引用
  dialogRef,

  // 暴露状态
  visible,
  position,

  // 暴露方法
  open,
  close,
  centerDialog,
})
</script>

<style scoped>
.qs-dialog-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  background-color: #f5f7fa;
  border-bottom: 1px solid #e4e7ed;
}

.qs-dialog-header-draggable {
  cursor: move;
}

.qs-dialog-title {
  font-size: 16px;
  font-weight: 500;
  color: #303133;
}

.qs-dialog-header-actions {
  display: flex;
  align-items: center;
}

.qs-dialog-body {
  position: relative;
  padding: 20px;
}

.qs-dialog-body.is-loading {
  min-height: 100px;
}

.qs-dialog-footer {
  padding: 10px 20px 20px;
  text-align: right;
}

:deep(.el-dialog) {
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}

:deep(.el-dialog__header) {
  margin: 0;
  padding: 0;
}

:deep(.el-dialog__headerbtn) {
  top: 16px;
  right: 16px;
}

:deep(.el-dialog__body) {
  padding: 0;
}

:deep(.el-dialog__footer) {
  padding: 0;
}
</style>
